package com.ffcs.crmd.tsp.client.core;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;

import com.ffcs.crmd.tsp.api.dto.client.TspCluster;
import com.ffcs.crmd.tsp.api.dto.client.TspClusterInstance;
import com.ffcs.crmd.tsp.api.dto.client.TspJob;
import com.ffcs.crmd.tsp.api.dto.client.TspJobDetail;
import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailDeath;
import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailParam;
import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailRetry;
import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailRunning;
import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailTrack;
import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailWaiting;
import com.ffcs.crmd.tsp.api.dto.client.TspJobGroup;
import com.ffcs.crmd.tsp.api.dto.client.TspJobIdentityInfo;
import com.ffcs.crmd.tsp.api.dto.client.TspSlice;
import com.ffcs.crmd.tsp.api.dto.client.TspSliceGroup;
import com.ffcs.crmd.tsp.api.dto.client.TspTaskConnectInfo;
import com.ffcs.crmd.tsp.api.dto.client.TspTaskIdentity;
import com.ffcs.crmd.tsp.api.dto.heart.ClientData;
import com.ffcs.crmd.tsp.api.dto.heart.HeartbeatData;
import com.ffcs.crmd.tsp.api.netty.INettyConfigClient;
import com.ffcs.crmd.tsp.client.log.ClientLogger;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.common.exception.TspRemotingException;
import com.ffcs.crmd.tsp.common.netty.RequestCode;
import com.ffcs.crmd.tsp.common.netty.RequestResult;
import com.ffcs.crmd.tsp.common.netty.enu.NettyRequestResult;
import com.ffcs.crmd.tsp.core.thread.ThreadFactoryImpl;
import com.ffcs.crmd.tsp.core.util.XmlUtil;

/**
 * 
 * 功能说明:客户端服务实例
 *
 * @author ZHONGFUHUA
 * 
 * @Date 2016年1月26日 下午2:52:13
 *
 *
 * 版本号  |   作者   |  修改时间   |   修改内容
 *
 */
public class TspClientIntance {
    
    /**
     * 日志
     */
    private final static Logger      LOG                      = ClientLogger.getLogger(LoggerName.ClientLoggerName);
    
    /**
     * 客户通信端Id(标识)
     */
    private String                   clientId;
    
    /**
     * 客户通信端服务实现
     */
    private TspClientImpl            clientImpl;
    
    /**
     * 客户通信端配置
     */
    private INettyConfigClient       nettyConfig;
    
    /**
     * 定时任务
     */
    private ScheduledExecutorService scheduledExecutorService = Executors
        .newSingleThreadScheduledExecutor(new ThreadFactoryImpl("TspClientScheduledThread-", 10));
    
    public TspClientIntance(INettyConfigClient nettyConfig) {
        this.clientId = nettyConfig.buildClientId();
        this.nettyConfig = nettyConfig;
        this.clientImpl = new TspClientImpl(nettyConfig);
    }
    
    public RequestResult createJob(TspJob request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a job to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_JOB);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult createJobDetail(TspJobDetail request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a job detail to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_JOB_DETAIL);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult createJobDetailParam(TspJobDetailParam request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a job detail param to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_JOB_DETAIL_PARAM);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult createJobGroup(TspJobGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a job group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_JOB_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult createJobIdentityInfo(TspJobIdentityInfo request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a job identity info to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_JOB_IDENTITY_INFO);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult createSlice(TspSlice request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a slice to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_SLICE);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult createSliceGroup(TspSliceGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a slice group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_SLICE_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult createTaskIdentity(TspTaskIdentity request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] create a task identity to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.CREATE_TASK_IDENTITY);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult deleteJob(TspJob request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a job to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_JOB);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult deleteJobDetail(TspJobDetail request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a job detail to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_JOB_DETAIL);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    
    
    public RequestResult deleteJobDetailDeath(TspJobDetailDeath request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a job detail death to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_JOB_DETAIL_DEATH);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult deleteJobDetailParam(TspJobDetailParam request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a job detail param to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_JOB_DETAIL_PARAM);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult deleteJobDetailRunning(TspJobDetailRunning request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a job detail running to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_JOB_DETAIL_RUNNING);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult deleteJobGroup(TspJobGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a job group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_JOB_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult deleteJobIdentityInfo(TspJobIdentityInfo request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a job identity info to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_JOB_IDENTITY_INFO);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult deleteSlice(TspSlice request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a slice to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_SLICE);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult deleteSliceGroup(TspSliceGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a slice group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_SLICE_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult deleteTaskIdentity(TspTaskIdentity request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] delete a task identity to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.DELETE_TASK_IDENTITY);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    /**
     * 功能说明: 获取客户通信端配置
     *
     * @return nettyConfig 客户通信端配置
     */
    public INettyConfigClient getNettyConfig() {
        return nettyConfig;
    }
    
    public RequestResult interruptJobDetailRunning(TspJobDetailRunning request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] interrupt job to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.INTERRUPT_JOB_DETAIL_RUNNING);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult pauseJob(TspJob request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] pause a job to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.PAUSE_JOB);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult pauseJobDetail(TspJobDetail request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] pause a job detail to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.PAUSE_JOB_DETAIL);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult pauseJobGroup(TspJobGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] pause a job group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.PAUSE_JOB_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryCluster(TspCluster request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query cluster server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_CLUSTER);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryClusterInstance(TspClusterInstance request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query cluster instance server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        return clientImpl.requestSync(request.getIpAddress(), XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_CLUSTER_INSTANCE);
    }
    
    
    public RequestResult queryJob(TspJob request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryJobDetail(TspJobDetail request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult queryJobDetailDeath(TspJobDetailDeath request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail death server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL_DEATH);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult queryJobDetailParam(TspJobDetailParam request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail param server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL_PARAM);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryJobDetailRetry(TspJobDetailRetry request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail retry server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL_RETRY);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryJobDetailRunning(TspJobDetailRunning request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail running server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL_RUNNING);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult queryJobDetailThreadInfo(TspJobDetailRunning request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail thread info server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL_THREAD_INFO);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryJobDetailTrack(TspJobDetailTrack request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail death track server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL_TRACK);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryJobDetailWaiting(TspJobDetailWaiting request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job detail waiting server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_DETAIL_WAITING);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult queryJobGroup(TspJobGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job group server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryJobIdentityInfo(TspJobIdentityInfo request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query job identity info server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_JOB_IDENTITY_INFO);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult querySlice(TspSlice request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query slice server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_SLICE);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult querySliceGroup(TspSliceGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query slice group server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_SLICE_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult queryTaskConnectInfo(TspTaskConnectInfo request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query task connect info server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_TASK_CONNECT_INFO);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult queryTaskIdentity(TspTaskIdentity request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] query task identity server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.QUERY_TASK_IDENTITY);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult resetJobDetailDeath(TspJobDetailDeath request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] reset a job detail death to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.RESET_JOB_DETAIL_DEATH);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult resetJobDetailRunning(TspJobDetailRunning request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] reset a job detail running to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.RESET_JOB_DETAIL_RUNNING);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult resumeJob(TspJob request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] resume a job to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.RESUME_JOB);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult resumeJobDetail(TspJobDetail request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] resume a job detail to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.RESUME_JOB_DETAIL);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult resumeJobGroup(TspJobGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] resume a job group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.RESUME_JOB_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    /**
     * 
     * 功能说明:发送心跳到服务端
     * 
     */
    private void sendHeartbeatToServer() {
        HeartbeatData heartbeatData = new HeartbeatData();
        ClientData clientData = new ClientData();
        clientData.setIp(nettyConfig.getClientIP());
        heartbeatData.setClientData(clientData);
        heartbeatData.setClientID(clientId);
        
        for (String addr : nettyConfig.getServerAddrList()) {
            try {
                clientImpl.sendHeartBeat(addr, heartbeatData);
                LOG.info("TSP-CLIENT: instance[{}] send a heart beat to server[{}].", clientId, addr);
            } catch (TspRemotingException e) {
                LOG.error("TSP-CLIENT: instance[{}] send a heart beat to server exception:", clientId, addr, e);
            }
        }
    }
    
    
    /**
     * 功能说明: 设置客户通信端配置
     *
     * @param nettyConfig 客户通信端配置
     */
    public void setNettyConfig(INettyConfigClient nettyConfig) {
        this.nettyConfig = nettyConfig;
    }
    
    
    /**
     * 
     * 功能说明:关闭
     * 
     */
    public void shutdown() throws TspRemotingException {
        this.clientImpl.shutdown();
        this.scheduledExecutorService.shutdown();
        LOG.info("TSP-CLIENT: intance shutdown ok - [{}].", this.clientId);
        System.out.println(String.format("TSP-CLIENT: intance shutdown ok - [%s].", clientId));
    }
    
    
    /**
     * 
     * 功能说明:启动
     * 
     */
    public void start() throws TspRemotingException {
        this.clientImpl.start();
        this.startScheduledTask();
        LOG.info("TSP-CLIENT: intance start ok - [{}].", this.clientId);
        System.out.println(String.format("TSP-CLIENT: intance start ok - [%s].", clientId));
    }
    
    /**
     * 
     * 功能说明:启动定时任务
     * 
     */
    private void startScheduledTask() {
        
        this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    TspClientIntance.this.sendHeartbeatToServer();
                } catch (Exception e) {
                    LOG.error("TSP-CLIENT: instance[{}] send heart beat to server[{}] exception:",
                        TspClientIntance.this.clientId,
                        TspClientIntance.this.nettyConfig.getServerAddr(), e);
                }
            }
        }, 1000, this.nettyConfig.getHeartbeatBrokerInterval(), TimeUnit.MILLISECONDS);
    }
    
    public RequestResult updateJob(TspJob request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] update a job to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.UPDATE_JOB);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    public RequestResult updateJobDetailParam(TspJobDetailParam request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] update a job detail param to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.UPDATE_JOB_DETAIL_PARAM);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
    
    public RequestResult updateJobGroup(TspJobGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] update a job group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.UPDATE_JOB_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }

    public RequestResult updateSlice(TspSlice request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] update a slice to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.UPDATE_SLICE);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    

    public RequestResult updateSliceGroup(TspSliceGroup request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] update a slice group to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.UPDATE_SLICE_GROUP);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }

    public RequestResult updateTaskIdentity(TspTaskIdentity request, long timeoutMillis) {
        LOG.debug("TSP-CLIENT: intance[{}] update a task identity to server[{}] body=[{}]", this.clientId, nettyConfig.getServerAddr(), request);
        RequestResult requestResult = null;
        for (String serverAddr : nettyConfig.getServerAddrList()) {
            requestResult = clientImpl.requestSync(serverAddr, XmlUtil.toXml(request), timeoutMillis, RequestCode.UPDATE_TASK_IDENTITY);
            if (requestResult.getRequestResultType() == NettyRequestResult.SUCCESS) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.FAIL) {
                break;
            } else if (requestResult.getRequestResultType() == NettyRequestResult.SEND_FAIL) {
                continue;
            }
        }
        return requestResult;
    }
    
}
